#ifndef NodeBase_h__
#define NodeBase_h__

#include <node.h>
#include <node_buffer.h>

// function and args
typedef v8::Value V8Value;
typedef v8::Object V8Object;
typedef v8::Array V8Array;
typedef v8::Function V8Function;
typedef v8::String V8String;
typedef v8::Boolean V8Boolean;
typedef v8::HandleScope V8HandleScope;

typedef v8::Handle<V8Value> V8ReturnType;
typedef v8::Local<V8Value> V8ValueRef;
typedef v8::Local<V8Object> V8ObjectRef;
typedef v8::Local<V8Array> V8ArrayRef;
typedef v8::Local<V8Function> V8FunctionRef;
typedef v8::Local<V8String> V8StringRef;
typedef v8::Handle<V8Boolean> V8BoolRef;

typedef v8::Persistent<V8Value> V8PersistentValue;
typedef v8::Persistent<V8Object> V8PersistentObject;
typedef v8::Persistent<V8Array> V8PersistentArray;
typedef v8::Persistent<V8Function> V8PersistentFunction;
typedef v8::Persistent<V8String> V8PersistentString;
typedef v8::Persistent<V8Boolean> V8PersistentBoolean;

#define V8FunScope() V8HandleScope scope
#ifdef _DEBUG
#  define V8ThrowTypeError(x) v8::ThrowException(v8::Exception::TypeError(v8::String::New(x)))
#else//_DEBUG
#  define V8ThrowTypeError(x)
#endif//_DEBUG
#define V8CheckArgLength(len) if (args.Length() < len) { V8ThrowTypeError("Wrong number of arguments, need \"" #len "\""); return scope.Close(v8::Undefined()); }
#define V8CheckArgType(i, type) if (!args[i]->Is##type()) { V8ThrowTypeError(V8ErrorFormat("Wrong argument[" #i "], need " #type " get %s.", V8GetValueTypeString(args[i]))); return scope.Close(v8::Undefined()); }
#define V8GetArg(i, type) (args[i]->type##Value())
#define V8GetArgObject(i) (args[i]->ToObject())
#define V8GetArgArray(i) (V8ArrayRef::Cast(args[i]))
#define V8DefPropKey(x) static V8PersistentValue x##Key = V8PersistentValue::New(V8String::NewSymbol(#x))
#define V8DefStaticValue(x, v) static V8PersistentValue x = V8PersistentValue::New(v)
#define V8PropKey(x) V8String::NewSymbol(#x)
#define V8CheckTypeReturnThrow(o, type, ret) if (!(o)->Is##type()) { V8ThrowTypeError(V8ErrorFormat("Wrong type of " #o ", need " #type " get %s.", V8GetValueTypeString(o))); return ret; }
#define V8CheckTypeReturnUndefinedThrow(o, type) V8CheckTypeReturnThrow(o, type, scope.Close(v8::Undefined()))

#define DEBUG_V8CheckTypeReturn(o, type, ret) if (!(o)->Is##type()) { return ret; }
#define DEBUG_V8CheckTypeReturnUndefined(o, type) DEBUG_V8CheckTypeReturn(o, type, scope.Close(v8::Undefined()))

#define V8VerifyReturn(x, ret) if (!(x)) { V8ThrowFormat(("Error:verify failed %s", #x)); return ret; }



#endif//NodeBase_h__
